﻿using System;
using System.Linq;
using Artemis;
using libtcod;
using RL.Components;
using RL.Systems;

namespace RL
{
    public class SettlersRL : IDisposable
    {
        private EntityWorld _world;
        private SystemManager _systemManager;

        private const string FONT = @"resources\arial12x12.png";

        private const int FPS = 30;

        public const int SCREEN_WIDTH = 120;
        public const int SCREEN_HEIGHT = 60;
        public const int MAIN_WIDTH = SCREEN_WIDTH * 3 / 4;
        public const int MAIN_HEIGHT = SCREEN_HEIGHT;
        public const int PANEL_WIDTH = SCREEN_WIDTH - MAIN_WIDTH;
        public const int PANEL_HEIGHT = SCREEN_HEIGHT;

        /// <summary>
        /// The left hand side main panel of the screen
        /// </summary>
        private readonly TCODConsole _main;
        /// <summary>
        /// The right hand side panel of the screen
        /// </summary>
        private readonly TCODConsole _panel;
        /// <summary>
        /// The background of the screen which is the blue border
        /// </summary>
        private readonly TCODConsole _screenBack;

        private TextForm FPSComponent;

        public SettlersRL()
        {          
            TCODConsole.setCustomFont(FONT, (int)(TCODFontFlags.Grayscale | TCODFontFlags.LayoutTCOD));
            TCODConsole.initRoot(SCREEN_WIDTH, SCREEN_HEIGHT, "SettlersRL", false, TCODRendererType.SDL);

            TCODMouse.showCursor(true);
            TCODSystem.setFps(1000);

            var mainConsole = new TCODConsole(MAIN_WIDTH, MAIN_HEIGHT);
            var panelConsole = new TCODConsole(PANEL_WIDTH, PANEL_HEIGHT);
            var map = new GameMap(MAIN_WIDTH, MAIN_HEIGHT);

            //_screenBack = new TCODConsole(MAIN_WIDTH, MAIN_HEIGHT);
            //_screenBack.setBackgroundColor(TCODColor.lightBlue);
            //foreach (var x in Enumerable.Range(0, SCREEN_WIDTH))
            //{
            //    foreach (var y in Enumerable.Range(0, SCREEN_HEIGHT))
            //    {
            //        _screenBack.printEx(x, y, TCODBackgroundFlag.Screen, TCODAlignment.CenterAlignment, " ");
            //    }
            //}

            //_panel = new TCODConsole(PANEL_WIDTH, PANEL_HEIGHT);
            //_panel.setForegroundColor(TCODColor.white);

            _world = new EntityWorld();

            _systemManager = _world.GetSystemManager();
            _systemManager.SetSystem(new MapRenderSystem(mainConsole), ExecutionType.Draw, 0);
            _systemManager.SetSystem(new SpatialRenderSystem(mainConsole), ExecutionType.Draw, 1);
            _systemManager.SetSystem(new TextRenderSystem(panelConsole), ExecutionType.Draw, 1);
            _systemManager.SetSystem(new RenderConsoleSystem(), ExecutionType.Draw, 2);
            _systemManager.SetSystem(new PlayerKeyboardControlSystem("PLAYER"), ExecutionType.Update);
            
            _systemManager.InitializeAll();

            var console = _world.CreateEntity();
            console.AddComponent(new ScreenBuffer(new Position(), mainConsole));
            console.Refresh();

            var sidePanel = _world.CreateEntity();
            sidePanel.AddComponent(new ScreenBuffer(new Position(MAIN_WIDTH, 0), panelConsole));
            sidePanel.Refresh();

            var player = _world.CreateEntity();
            player.AddComponent(new Position(5, 5));
            player.AddComponent(new SpatialForm(SpatialFormType.Player));
            player.SetTag("PLAYER");
            player.Refresh();

            var mapEntity = _world.CreateEntity();
            mapEntity.AddComponent(new Position());
            mapEntity.AddComponent(new GameMap(MAIN_WIDTH, MAIN_HEIGHT));
            mapEntity.Refresh();

            FPSComponent = new TextForm{Text = string.Format("{0, 4} fps", 0)};            
            var fpsDisplay = _world.CreateEntity();
            fpsDisplay.AddComponent(new Position(20,0));
            fpsDisplay.AddComponent(FPSComponent);
            fpsDisplay.Refresh();
        }

        public static bool Quit { get; set; }

        public void Run()
        {
            DateTime dt = DateTime.Now;
            int frameCounter = 0;

            Quit = false;
            while (!Quit)
            {
                TimeSpan elapsed = DateTime.Now - dt;
                dt = DateTime.Now;
                frameCounter++;

                _world.LoopStart();
                _world.SetDelta(elapsed.Milliseconds);
                _world.GetSystemManager().UpdateSynchronous(ExecutionType.Update);
                _world.GetSystemManager().UpdateSynchronous(ExecutionType.Draw);

                FPSComponent.Text = string.Format("{0, 4} fps", TCODSystem.getFps());
                TCODConsole.flush();
            }
        }

        public void Dispose()
        {
            
        }
    }

    public class TextForm : Component
    {
        public string Text { get; set; }
        public TextForm(){}
        public TextForm(string text)
        {
            Text = text;
        }
    }
}